﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Ruleweaver.Rules.CheckMethods
{
	[ContractClass(typeof(RuleweaverNumberCheckMethodContract))]
	public abstract class RuleweaverNumberCheckMethod : MultiTypeCheckMethod
	{
		internal RuleweaverNumberCheckMethod()
		{}

		protected override IEnumerable<Type> TargetTypes
		{
			get
			{
				yield return typeof(decimal);
				yield return typeof(double);
				yield return typeof(float);
				yield return typeof(int);
				yield return typeof(long);
			}
		}

		protected override MethodInfo GetMethod(Type targetType, Type checkType)
		{
			return typeof(Checkable)
				.GetMethods(BindingFlags.Public | BindingFlags.Static)
				.Where(method => method.Name == MethodName)
				.Where(method => method.GetParameters().First().ParameterType == checkType)
				.First();
		}

		protected abstract string MethodName { get; }
	}

	[ContractClassFor(typeof(RuleweaverNumberCheckMethod))]
	internal abstract class RuleweaverNumberCheckMethodContract : RuleweaverNumberCheckMethod
	{
		protected override string MethodName
		{
			get
			{
				Contract.Ensures(!String.IsNullOrEmpty(Contract.Result<string>()));

				return null;
			}
		}
	}
}